package main

import "C"
import (
	"fmt"
	"log"
	"syscall"
	"unsafe"
)


func IntPtr(n int) uintptr {
	return uintptr(n)
}

func StrPtr(s string) uintptr {
	return uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(s)))
}

// 已*byte传入易语言
func EStrPtr(s string) uintptr {
	b,_:= syscall.BytePtrFromString(s)
	res := uintptr(unsafe.Pointer(b))
	return  res
}


func lib_add(a,b int) {
	dllTest,err:=syscall.LoadLibrary("./etest.dll")
	if err!= nil{
		fmt.Println("载入dll出错:",err.Error())
		syscall.Exit(0)
	}
	defer syscall.FreeLibrary(dllTest)
	add,err:=syscall.GetProcAddress(dllTest,"add")
	if err!= nil{
		fmt.Println("调用函数出错:",err.Error())
		syscall.Exit(0)
	}
	ret,_,err:=syscall.Syscall(add, 2, uintptr(a), uintptr(b), 0)
	if err != nil{
		fmt.Println(ret)
		syscall.Exit(0)
	}
}
/*
func lib_str_test(name string) {
	dll:=syscall.NewLazyDLL("./etest.dll")
	str_test:=dll.NewProc("show_str")
	ret,_,err:=str_test.Call(EStrPtr(name))
	if err!=nil{
		anem := (*string)(unsafe.Pointer(uintptr(ret)))
		b,e:=syscall.UTF16PtrFromString(*anem)
		if e!=nil{
			fmt.Println("转换错误:",e.Error())
			syscall.Exit(0)
		}
		fmt.Println(*b)
	}
}
*/
type Mys struct {
	aStr unsafe.Pointer
	a1 string
}

var mm Mys

func lib_ret_str(name string) {
	dll:=syscall.NewLazyDLL("./etest.dll")
	defer syscall.FreeLibrary(syscall.Handle(dll.Handle()))
	str_test:=dll.NewProc("ret_str")
	//ret,_,err:=str_test.Call(EStrPtr(name))
	ret,_,err:=str_test.Call(EStrPtr(name))
	if err!=nil {
		// 调用cgo来处理易语言返回的字符串
		a1 := (*C.char)(unsafe.Pointer(ret))
		//b := (*byte)(unsafe.Pointer(*(*uintptr)(unsafe.Pointer(&ret))+1))
		a3 := C.GoString(a1)
		log.Println("返回值:", a3)
	}
}


func MyStr(str string) {
	fmt.Println("传入数据:",str)
	a:=EStrPtr(str)
	//a:=uintptr(unsafe.Pointer(&str))
	astr:=(*string)(unsafe.Pointer(a))
	//b := (*byte)(unsafe.Pointer(*(*uintptr)(unsafe.Pointer(a)) + 1))
	fmt.Println("返回数据",*astr)
}

func main() {
	name := "来一个很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长的中文"
	lib_ret_str(name)
}
